]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
environment: Add convenience method for property transitions
authorFlorian Müllner <fmuellner@gnome.org>
Sat, 10 Jun 2017 02:14:12 +0000 (04:14 +0200)
committerFlorian Müllner <fmuellner@gnome.org>
Tue, 6 Aug 2019 21:54:29 +0000 (23:54 +0200)
While we are now using implicit animations for all animatable properties,
there are still some cases where we animate other actor properties (for
example from a custom subclass) or associated objects like effects.

Those can still be animated using Clutter animations, as long as we use
the explicit API rather than implicit animations. Again this API is
cumbersome and tricky enough to warrant a convenience wrapper.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/666

js/ui/environment.js

index d36521736e62663fb80fb0a07ff62e46b7fd612f..b00b74dd9546f2e13091d20bd09741443e0ae6af 100644 (file)
@@ -90,6 +90,25 @@ function _makeEaseCallback(params) {
     };
 }
 
+function _getPropertyTarget(actor, propName) {
+    if (!propName.startsWith('@'))
+        return [actor, propName];
+
+    let [type, name, prop] = propName.split('.');
+    switch (type) {
+    case '@layout':
+        return [actor.layout_manager, name];
+    case '@actions':
+        return [actor.get_action(name), prop];
+    case '@constraints':
+        return [actor.get_constraint(name), prop];
+    case '@effects':
+        return [actor.get_effect(name), prop];
+    }
+
+    throw new Error(`Invalid property name ${propName}`);
+}
+
 function _easeActor(actor, params) {
     actor.save_easing_state();
 
@@ -125,6 +144,45 @@ function _easeActor(actor, params) {
     actor.restore_easing_state();
 }
 
+function _easeActorProperty(actor, propName, target, params) {
+    // Avoid pointless difference with ease()
+    if (params.mode)
+        params.progress_mode = params.mode;
+    delete params.mode;
+
+    if (params.duration)
+        params.duration = adjustAnimationTime(params.duration);
+    let duration = Math.floor(params.duration || 0);
+
+    let callback = _makeEaseCallback(params);
+
+    // cancel overwritten transition
+    actor.remove_transition(propName);
+
+    if (duration == 0) {
+        let [obj, prop] = _getPropertyTarget(actor, propName);
+        obj[prop] = target;
+
+        if (callback)
+            callback(true);
+
+        return;
+    }
+
+    let pspec = actor.find_property(propName);
+    let transition = new Clutter.PropertyTransition(Object.assign({
+        property_name: propName,
+        interval: new Clutter.Interval({ value_type: pspec.value_type }),
+        remove_on_complete: true
+    }, params));
+    actor.add_transition(propName, transition);
+
+    transition.set_to(target);
+
+    if (callback)
+        _trackTransition(transition, callback);
+}
+
 function _loggingFunc(...args) {
     let fields = { 'MESSAGE': args.join(', ') };
     let domain = "GNOME Shell";
@@ -173,6 +231,9 @@ function init() {
     Clutter.Actor.prototype.ease = function(props, easingParams) {
         _easeActor(this, props, easingParams);
     };
+    Clutter.Actor.prototype.ease_property = function(propName, target, params) {
+        _easeActorProperty(this, propName, target, params);
+    };
 
     Clutter.Actor.prototype.toString = function() {
         return St.describe_actor(this);